﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.Mvc;
using System.Xml;
using System.Xml.Serialization;
using DAL.Repositories;

namespace Web.Controllers
{
    [HandleError]
    public class XmlController : Controller
    {
        public ActionResult Search(int id, int roomsNumberId, int areaId, int priceId)
        {
            var apartmentRep = new ApartmentRepository();
            var apartments = apartmentRep.Search(id, roomsNumberId, areaId, priceId);

            //var xmlString = ToXml(apartments, apartments.GetType());
            var xmlString = ToXmlNew(apartments);
            return this.Content(xmlString, "text/xml");
        }

        public ActionResult SearchByFloor(int id)
        {
            var apartmentRep = new ApartmentRepository();
            var apartments = apartmentRep.GetBasicInfoByFloor(id);

            //var xmlString = ToXml(apartments, apartments.GetType());
            var xmlString = ToXmlNew(apartments);
            return this.Content(xmlString, "text/xml");
        }

        public ActionResult SearchByKeyword(string id)
        {
            var apartmentRep = new ApartmentRepository();
            var apartments = apartmentRep.SearchByKeyword(id);

            var xmlString = ToXmlNew(apartments);
            return this.Content(xmlString, "text/xml");
        }

        public ActionResult CodeList(string id)
        {
            var codeListRep = new CodeListRepository();
            
            switch (id.ToLower())
            {
                case "areainterval":
                    var areaIntervalsList = codeListRep.ReadAreaIntervals();
                    var areaIntervalsXmlString = ToXmlNew(areaIntervalsList);
                    return Content(areaIntervalsXmlString, "text/xml");
                case "priceinterval":
                    var priceIntervalsList = codeListRep.ReadPriceIntervals();
                    var priceIntervalsXmlString = ToXmlNew(priceIntervalsList);
                    return Content(priceIntervalsXmlString, "text/xml");
                case "floor":
                    var floorsList = codeListRep.ReadFloors();
                    var floorsXmlString = ToXmlNew(floorsList);
                    return Content(floorsXmlString, "text/xml");
                case "roomsnumber":
                    var roomsNumbersList = codeListRep.ReadRoomsNumber();
                    var roomsNumbersXmlString = ToXmlNew(roomsNumbersList);
                    return Content(roomsNumbersXmlString, "text/xml");
            }

            return null;
        }

        public ActionResult Apartment(int id)
        {
            var apartmentRep = new ApartmentRepository();
            var apartment = apartmentRep.Read(id);

            var xmlString = ToXmlNew(apartment);

            //xml to insert (graphics node)
            var code = apartment.Code;
            var buildingName = code.Remove(code.IndexOf('-'));

            var apartmentNum = String.Empty;
            var counter = 0;
            foreach (var letter in code)
            {
                if(letter == '.')
                {
                    counter++;
                }
                else if (counter == 2) 
                {
                    apartmentNum += letter;
                }
            }

            code = buildingName + "_" + apartmentNum;

            var tempCode = "C-4-14";
            var graphicXmlString = "<graphics>" +
                                       "<layout>www.centar-bundek.hr/graphic/layout/" + tempCode + ".jpg</layout>" +
                                       "<flrlayout>www.centar-bundek.hr/graphic/floor-layout/" + code + ".jpg</flrlayout>" +
                                       "<flrlayoutzoom>www.centar-bundek.hr/graphic/floor-layout/zoom/" + code + ".jpg</flrlayoutzoom>" +
                                       "<sidelayout>www.centar-bundek.hr/graphic/side/" + tempCode + ".jpg</sidelayout>" +
                                   "</graphics>";

            //create xml document to append new node 
            var doc = new XmlDocument();
            doc.LoadXml(xmlString);

            //create xml fragment that will be append 
            var docFrag = doc.CreateDocumentFragment();
            docFrag.InnerXml = graphicXmlString;

            //append fragment 
            doc.DocumentElement.AppendChild(docFrag);

            //convert xml doc to xml string 
            var sw = new StringWriter();
            var tx = new XmlTextWriter(sw);
            doc.WriteTo(tx);

            xmlString = sw.ToString();

            return this.Content(xmlString, "text/xml");
        }

        public static string ToXml(object obj, Type objType)
        {
            var ser = new XmlSerializer(objType, "http://www.w3.org/2001/XMLSchema");
            var memStream = new MemoryStream();
            var xmlWriter = new XmlTextWriter(memStream, Encoding.UTF8) {Namespaces = true};
            ser.Serialize(xmlWriter, obj, GetNamespaces());
            xmlWriter.Close();
            memStream.Close();
            var xml = Encoding.UTF8.GetString(memStream.GetBuffer());
            xml = xml.Substring(xml.IndexOf(Convert.ToChar(60)));
            xml = xml.Substring(0, (xml.LastIndexOf(Convert.ToChar(62)) + 1));
            return xml;
        }

        public static string ToXmlNew(object entity)
        {
            var myNamespaces = new XmlSerializerNamespaces();
            myNamespaces.Add("xs", "http://www.w3.org/2001/XMLSchema");
            myNamespaces.Add("xsi", "http://www.w3.org/2001/XMLSchema-instance");

            var xs = new XmlSerializer(entity.GetType());
            using (var memoryStream = new MemoryStream())
            {
                var settings = new XmlWriterSettings()
                {
                    Encoding = Encoding.UTF8
                };
                using (var writer = XmlWriter.Create(memoryStream, settings))
                {
                    xs.Serialize(writer, entity);
                }
                
                var xml = Encoding.UTF8.GetString(memoryStream.GetBuffer());
                xml = xml.Substring(xml.IndexOf(Convert.ToChar(60)));
                xml = xml.Substring(0, (xml.LastIndexOf(Convert.ToChar(62)) + 1));
                return xml;
            }
        }

        public static XmlSerializerNamespaces GetNamespaces()
        {
            var ns = new XmlSerializerNamespaces();
            ns.Add("xs", "http://www.w3.org/2001/XMLSchema");
            ns.Add("xsi", "http://www.w3.org/2001/XMLSchema-instance");
            return ns;
        }
    }
}
